﻿using RockBus.DataContracts;
using RockBus.Transport.Interfaces;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace RockBus.Transport.Wcf
{
    public class ServiceHostFactory
    {
        public ServiceHostFactory()
        {
            this.ServiceEndpointFactory = new ServiceEndpointFactory();
        }

        private IServiceEndpointFactory ServiceEndpointFactory { get; set; }

        public ServiceHost CreateServiceHost(object singletonInstance, params EndpointInfo[] endpointInfos)
        {
            return this.CreateServiceHost(singletonInstance, (IEnumerable<EndpointInfo>)endpointInfos);
        }

        public ServiceHost CreateServiceHost(object singletonInstance, IEnumerable<EndpointInfo> endpointInfos)
        {
            var sh = new ServiceHost(singletonInstance);
            this.AddDynamicServiceEndpoints(sh, endpointInfos);
            return sh;
        }

        public ServiceHost CreateServiceHost(IEnumerable<EndpointInfo> endpointInfos)
        {
            return this.CreateServiceHost((IEnumerable<EndpointInfo>)endpointInfos);
        }

        public ServiceHost CreateServiceHost<T>(params EndpointInfo[] endpointInfos)
        {
            var sh = new ServiceHost(typeof(T));
            this.AddDynamicServiceEndpoints(sh, endpointInfos);
            return sh;
        }

        private void AddDynamicServiceEndpoints(ServiceHost serviceHost, IEnumerable<EndpointInfo> endpointInfos)
        {
            var seps = new List<ServiceEndpoint>();
            foreach (EndpointInfo ei in endpointInfos)
            {
                var sep = this.ServiceEndpointFactory.CreateDynamicServiceEndpoint(serviceHost, ei);
                seps.Add(sep);
                ei.Address = sep.Address.ToString();
            }

            serviceHost.Description.Endpoints.Clear();
            foreach (var sep in seps)
            {
                serviceHost.AddServiceEndpoint(sep);
            }
        }
    }
}